home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / ear / mui23dev.lha / MUI / Developer / Modula / Demo / Class1.mod < prev    next >
Text File  |  1994-06-27  |  9KB  |  294 lines

  1. MODULE Class1;
  2.  
  3. (*$ StackChk:=FALSE   NilChk:=FALSE   EntryClear:=FALSE
  4.     RangeChk:=FALSE
  5. *)
  6.  
  7.  
  8. (*
  9. ** Class1
  10. ** the M2 interpretation of the famous class written by Stefan Stuntz
  11. ** for MUI in C.
  12. ** This demonstration was performed by Christian 'Kochtopf' Scholz in
  13. ** order to show how the same is done in M2. 
  14. ** (ofcourse inspired by class1.c ;-)   )
  15. **
  16. ** please note that there are some foldmarkers inside this file, which
  17. ** are used by GoldEd.
  18. *)
  19.  
  20. (*{{{  "Imports" *)
  21.  
  22. IMPORT MD:MuiD;
  23. IMPORT ML:MuiL;
  24. IMPORT MM:MuiMacros;
  25. IMPORT R;
  26. IMPORT Arts;
  27. FROM SYSTEM     IMPORT ADDRESS, LONGSET, TAG, CAST, ADR;
  28. FROM ExecL      IMPORT Wait;
  29. FROM MuiMacros  IMPORT MakeHook, HookDef, NoteClose, set;
  30. FROM MuiSupport IMPORT fail, DoMethod, DOMethod, APTR;
  31. FROM IntuitionD IMPORT IClassPtr, ObjectPtr, DrawPens, DrawInfo, Msg, IClass;
  32. FROM IntuitionL IMPORT FreeClass, MakeClass, NewObjectA;
  33. FROM MuiClasses IMPORT mpAskMinMax, mpAskMinMaxPtr, mpDraw, mpDrawPtr,
  34.                        MADFlagSet, MADFlags,
  35.                        OBJ_rp, OBJ_dri, OBJ_mleft, OBJ_mtop, OBJ_mbottom, OBJ_mright,
  36.                        mpSetUp, mMinMax, FillMinMaxInfo, MakeDispatcher;
  37. FROM AmigaLib   IMPORT DoSuperMethodA;
  38. FROM GraphicsL  IMPORT SetAPen, Move, Draw;
  39. FROM GraphicsD  IMPORT RastPortPtr;
  40. FROM UtilityD   IMPORT HookPtr, Hook, tagDone, tagEnd;
  41. FROM Terminal   IMPORT Format;
  42.  
  43. (*}}}*)
  44. (*{{{  "the class" *)
  45.  
  46. (***************************************************************************)
  47. (* Here is the beginning of our simple new class...                        *)
  48. (***************************************************************************)
  49.  
  50. (*
  51. ** This is an example for the simplest possible MUI class. It's just some
  52. ** kind of custom image and supports only two methods: 
  53. ** mAskMinMax and mDraw.
  54. *)
  55.  
  56. (*
  57. ** This is the instance data for our custom class.
  58. ** Since it's a very simple class, it contains just a dummy entry.
  59. *)
  60.  
  61. TYPE Data = RECORD
  62.                 dummy       :   LONGINT;
  63.             END;
  64.  
  65. VAR  MyData     :   Data;
  66.  
  67. (*{{{  "mAskMinMax" *)
  68. (*
  69. ** AskMinMax method will be called before the window is opened
  70. ** and before layout takes place. We need to tell MUI the
  71. ** minimum, maximum and default size of our object.
  72. *)
  73.  
  74. PROCEDURE mAskMinMax(cl : IClassPtr; obj : ObjectPtr; msg : mpAskMinMaxPtr) : ADDRESS;
  75.     VAR     dummy   : ADDRESS;
  76.     BEGIN
  77.         (*
  78.         ** let our superclass first fill in what it thinks about sizes.
  79.         ** this will e.g. add the size of frame and inner spacing.
  80.         *)
  81.  
  82.         dummy:=DoSuperMethodA(cl,obj,msg);
  83.  
  84.         (*
  85.         ** now add the values specific to our object. note that we
  86.         ** indeed need to *add* these values, not just set them!
  87.         *)
  88.  
  89.         msg^.MinMaxInfo^.MinWidth  := msg^.MinMaxInfo^.MinWidth +100;
  90.         msg^.MinMaxInfo^.DefWidth  := msg^.MinMaxInfo^.DefWidth +120;
  91.         msg^.MinMaxInfo^.MaxWidth  := msg^.MinMaxInfo^.MaxWidth +500;
  92.  
  93.         msg^.MinMaxInfo^.MinHeight := msg^.MinMaxInfo^.MinHeight +40;
  94.         msg^.MinMaxInfo^.DefHeight := msg^.MinMaxInfo^.DefHeight +90;
  95.         msg^.MinMaxInfo^.MaxHeight := msg^.MinMaxInfo^.MaxHeight +300;
  96.  
  97.         (*
  98.         ** please note that there is a PROCEDURE defined in MUIClasses,
  99.         ** which does the settings of the MinMaxInfo.
  100.         ** just call
  101.         **  FillMinMaxInfo(msg, 100, 120, 500, 40, 90, 300);
  102.         ** in order to do the same as above in one line.
  103.         *)
  104.  
  105.         RETURN NIL;
  106.     END mAskMinMax;
  107. (*}}}*)
  108. (*{{{  "mDraw" *)
  109. (*
  110. ** Draw method is called whenever MUI feels we should render
  111. ** our object. This usually happens after layout is finished
  112. ** or when we need to refresh in a simplerefresh window.
  113. ** Note: You may only render within the rectangle
  114. **       OBJ_mleft(obj), OBJ_mtop(obj), OBJ_mwidth(obj), OBJ_mheight(obj).
  115. *)
  116.  
  117. PROCEDURE mDraw(cl : IClassPtr; obj : ObjectPtr; msg : mpDrawPtr) : ADDRESS;
  118.     VAR
  119.             i       : INTEGER;
  120.             dummy   : ADDRESS;
  121.             mt, ml, mr, mb : INTEGER;
  122.     
  123.     BEGIN
  124.  
  125.         (*
  126.         ** let our superclass draw itself first, area class would
  127.         ** e.g. draw the frame and clear the whole region. What
  128.         ** it does exactly depends on msg->flags.
  129.         *)
  130.  
  131.         dummy:=DoSuperMethodA(cl,obj,msg);
  132.  
  133.         (*
  134.         ** if drawObject isn't in MADFlagSet, we shouldn't draw anything.
  135.         ** MUI just wanted to update the frame or something like that.
  136.         *)
  137.  
  138.         IF (drawObject IN msg^.flags) THEN
  139.  
  140.             (*
  141.             ** ok, everything ready to render...
  142.             *)
  143.  
  144.             mt:=OBJ_mtop(obj);
  145.             ml:=OBJ_mleft(obj);
  146.             mr:=OBJ_mright(obj);
  147.             mb:=OBJ_mbottom(obj);
  148.  
  149.  
  150.             SetAPen(OBJ_rp(obj), OBJ_dri(obj)^.pens^[textPen]);
  151.  
  152.             FOR i:=ml TO mr BY 5 DO
  153.                 Move(OBJ_rp(obj), ml, mb);
  154.                 Draw(OBJ_rp(obj), i, mt);
  155.                 Move(OBJ_rp(obj), mr, mb);
  156.                 Draw(OBJ_rp(obj), i, mt);
  157.             END;
  158.  
  159.         END; (* if *)
  160.  
  161.         RETURN NIL;
  162.  
  163.     END mDraw;
  164.  
  165. (*}}}*)
  166. (*{{{  "MyDispatcher" *)
  167. (*
  168. ** Here comes the dispatcher for our custom class. We only need to
  169. ** care about mAskMinMax and mDraw in this simple case.
  170. ** Unknown/unused methods are passed to the superclass immediately.
  171. *)
  172.  
  173. PROCEDURE MyDispatcher(cl : IClassPtr; obj : ADDRESS; msg : ADDRESS) : ADDRESS;
  174.  
  175.     BEGIN
  176.  
  177.         (* sorry, no CASE here, because the range is too big... *)
  178.  
  179.         IF CAST(Msg, msg)^.methodID=MD.mmAskMinMax THEN
  180.             RETURN mAskMinMax(cl, obj, msg);
  181.         ELSIF CAST(Msg, msg)^.methodID=MD.mmDraw THEN
  182.             RETURN mDraw(cl, obj,msg);
  183.         ELSE
  184.             RETURN DoSuperMethodA(CAST(IClassPtr, cl), obj, msg);
  185.         END;
  186.  
  187.     END MyDispatcher;
  188.  
  189. (*}}}*)
  190. (*}}}*)
  191. (***************************************************************************)
  192. (* Thats all there is about it. Now lets see how things are used...        *)
  193. (***************************************************************************)
  194. (*{{{  "VAR" *)
  195. VAR app, window, MyObj, SuperClass  : APTR;
  196.     myObj                           : APTR;
  197.     MyClass                         : IClassPtr;
  198.     signals                         : LONGSET;
  199.     running                         :=BOOLEAN{TRUE};
  200.     myHookPtr                       : HookPtr;
  201.     buffer, buffer2                 : ARRAY[0..60] OF LONGINT;
  202.     NULL                            :=ADDRESS{NIL};
  203.     du                              : BOOLEAN;
  204. (*}}}*)
  205. (*{{{  "usage of the class" *)
  206. BEGIN
  207.  
  208.     (* Get a pointer to the superclass. MUI will lock this *)
  209.     (* and prevent it from being flushed during you hold   *)
  210.     (* the pointer. When you're done, you have to call     *)
  211.     (* moFreeClass() to release this lock.                 *)
  212.  
  213.     SuperClass:=ML.moGetClass(ADR(MD.mcArea));
  214.     IF SuperClass=NIL THEN fail(NULL, "Superclass for the new class not found,"); END;
  215.  
  216.     (* create the new class *)
  217.     MyClass:=MakeClass(NIL, NIL, SuperClass, SIZE(MyData), LONGSET{});
  218.     IF MyClass=NIL THEN 
  219.         ML.moFreeClass(SuperClass); 
  220.         fail(NULL, "Failed to create class!");
  221.     END;
  222.  
  223.     (* set the dispatcher for the new class *)
  224.     
  225.     MakeDispatcher(MyDispatcher, MyClass);
  226.     
  227.  
  228.     (* create a little GUI with our new class *)
  229.  
  230.     MyObj   := NewObjectA(MyClass, NIL, TAG(buffer,
  231.                                 MD.maFrame,             MD.mvFrameText,
  232.                                 MD.maBackground,        MD.miBACKGROUND,
  233.                                 tagDone));
  234.  
  235.     window  := MM.WindowObject(TAG(buffer,
  236.                     MD.maWindowTitle,           ADR("A test of our custom class"),
  237.                     MM.WindowContents,          MM.VGroup(TAG(buffer2,
  238.                                                     MM.Child,       MyObj,
  239.                                                     tagEnd)),
  240.                     tagEnd));
  241.  
  242.     app   := MM.ApplicationObject(TAG(buffer,
  243.         MD.maApplicationTitle,        ADR("M2Class1"),
  244.         MD.maApplicationAuthor,       ADR("Christian Scholz and Stefan Stuntz"),
  245.         MD.maApplicationVersion,      ADR("$VER: M2Class1 1.0 (18.04.94)"),
  246.         MD.maApplicationCopyright,    ADR("© KT SS"),
  247.         MD.maApplicationDescription,  ADR("demonstrates how to write own classes in M2!"),
  248.         MD.maApplicationBase,         ADR("M2CLASS1"),
  249.         MM.SubWindow,                 window,
  250.         tagEnd));
  251.  
  252.  
  253.     IF app=NIL THEN fail(app, "failed to create application!!"); END;
  254.  
  255.     NoteClose(app, window, MD.mvApplicationReturnIDQuit);   (* set up a notify on closing the window *)
  256.  
  257.  
  258. (*
  259. ** Input loop...
  260. *)
  261.  
  262.     set(window,MD.maWindowOpen,1);
  263.  
  264.     WHILE running DO
  265.  
  266.                 CASE DOMethod(app, TAG(buffer,
  267.                        MD.mmApplicationInput, ADR(signals))) OF
  268.  
  269.                 |   MD.mvApplicationReturnIDQuit :
  270.                             running:=FALSE;
  271.                 ELSE
  272.  
  273.                 END;
  274.  
  275.                 IF running AND (signals <> LONGSET{} ) THEN signals:=Wait(signals);
  276.                                            END;
  277.  
  278.     END; (* While *)
  279.  
  280.     set(window,MD.maWindowOpen,0);
  281.  
  282.  
  283. (*
  284. ** Shut down...
  285. *)
  286.  
  287.     ML.mDisposeObject(app);             (* free our application resources *)
  288.     du:=FreeClass(MyClass);             (* free our own class *)
  289.     ML.moFreeClass(SuperClass);         (* free our SuperClass *)
  290.     fail(NULL,"");                      (* and the end..... *)
  291. (*}}}*)
  292. END Class1.
  293.  
  294.